package x10.eventServices.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.TitledBorder;

import x10.enums.Device;
import x10.enums.Function;
import x10.enums.House;
import x10.enums.InterfaceMessage;
import x10.enums.Media;
import x10.enums.Remote;
import x10.event.X10Command;
import x10.event.X10InterfaceRequest;
import x10.event.X10Remote;
import x10.properties.PropertiesManager;

public class GUI extends JFrame {
    private static final long serialVersionUID = 1L;
    private GUIManager guiManager;
    private PropertiesManager properties;
    
    private JPanel rootPanel = null;
    private JPanel x10CommandPanel = null;
    private JPanel x10RemotePanel = null;
    private JPanel x10InterfacePanel = null;
    private JPanel logPanel = null;
    private JScrollPane readLogScrollPane = null;
    private JButton sendX10CommandButton = null;
    private JButton sendX10RemoteButton = null;
    private JButton clearButton = null;
    private JButton pauseButton = null;
    private JButton statusButton = null;
    private JButton suppressDuplicatesButton = null;
    private JTextArea readLogTextArea = null;
    private JComboBox commandHouseCodeComboBox = null;
    private JComboBox commandMediaComboBox = null;
    private JComboBox remoteHouseCodeComboBox = null;
    private JComboBox deviceCodeComboBox = null;
    private JComboBox functionCodeComboBox = null;
    private JComboBox remoteCodeComboBox = null;
    private boolean pause = false;
    private boolean suppressDuplicateLogEntries;

    public GUI(GUIManager guiManager, PropertiesManager properties) {
        super();
        this.guiManager = guiManager;
        this.properties = properties;
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initialize();
    }

    private void initialize() {
        this.setTitle("X10 JAVA");
        this.setContentPane(getRootPanel());
        this.pack();
        this.setSize(1000, 700);
        this.setVisible(true);
        suppressDuplicateLogEntries = properties.getBoolean("eventService.gui.suppress.duplicate.entries", true);
    }
	
    /**
     * @return the suppressDuplicateLogEntries
     */
    public boolean isSuppressDuplicateLogEntries() {
        return suppressDuplicateLogEntries;
    }

    private JPanel getRootPanel() {
        if (rootPanel == null) {
            rootPanel = new JPanel();
            rootPanel.setLayout(new BoxLayout(getRootPanel(), BoxLayout.Y_AXIS));
            rootPanel.add(getX10CommandPanel(),null);
            rootPanel.add(getX10RemotePanel(),null);
            rootPanel.add(getX10InterfacePanel(),null);
            rootPanel.add(getLogPanel(),null);
            rootPanel.add(getReadLogScrollPane(), null);
        }
        return rootPanel;
    }

		
    private JPanel getX10CommandPanel() {
        if (x10CommandPanel == null) {
            FlowLayout flowLayout = new FlowLayout();
            flowLayout.setVgap(1);
            flowLayout.setAlignment(FlowLayout.LEFT);
            x10CommandPanel = new JPanel();
            x10CommandPanel.setLayout(flowLayout);
            x10CommandPanel.setBorder(BorderFactory.createTitledBorder(null,"X10 Command", TitledBorder.DEFAULT_JUSTIFICATION,TitledBorder.DEFAULT_POSITION, new Font("Dialog",Font.BOLD,12), new Color(51, 51, 51)));
            x10CommandPanel.add(getCommandHouseCodeComboBox(), null);
            x10CommandPanel.add(getDeviceCodeComboBox(), null);
            x10CommandPanel.add(getFunctionCodeComboBox(), null);
            x10CommandPanel.add(getCommandMediaComboBox(), null);
            x10CommandPanel.add(getSendX10CommandButton(),null);
        }
        return x10CommandPanel;
    }
	
    private JPanel getX10RemotePanel() {
        if (x10RemotePanel == null) {
            FlowLayout flowLayout = new FlowLayout();
            flowLayout.setVgap(1);
            flowLayout.setAlignment(FlowLayout.LEFT);
            x10RemotePanel = new JPanel();
            x10RemotePanel.setLayout(flowLayout);
            x10RemotePanel.setBorder(BorderFactory.createTitledBorder(null,"X10 Remote", TitledBorder.DEFAULT_JUSTIFICATION,TitledBorder.DEFAULT_POSITION, new Font("Dialog",Font.BOLD,12), new Color(51, 51, 51)));
            x10RemotePanel.add(getRemoteCodeComboBox(), null);
            x10RemotePanel.add(getRemoteHouseCodeComboBox(), null);
            x10RemotePanel.add(getSendX10RemoteButton(),null);
//            writePanel.add(getDeviceCodeComboBox(), null);
//            writePanel.add(getFunctionCodeComboBox(), null);
//            writePanel.add(getStatusButton(),null);
        }
        return x10RemotePanel;
    }
	
    private JPanel getX10InterfacePanel() {
        if (x10InterfacePanel == null) {
            FlowLayout flowLayout = new FlowLayout();
            flowLayout.setVgap(1);
            flowLayout.setAlignment(FlowLayout.LEFT);
            x10InterfacePanel = new JPanel();
            x10InterfacePanel.setLayout(flowLayout);
            x10InterfacePanel.setBorder(BorderFactory.createTitledBorder(null,"X10 Interface", TitledBorder.DEFAULT_JUSTIFICATION,TitledBorder.DEFAULT_POSITION, new Font("Dialog",Font.BOLD,12), new Color(51, 51, 51)));
            x10InterfacePanel.add(getInterfaceStatusButton(),null);
        }
        return x10InterfacePanel;
    }

    private JPanel getLogPanel() {
        if (logPanel == null) {
            FlowLayout flowLayout = new FlowLayout();
            flowLayout.setVgap(1);
            flowLayout.setAlignment(FlowLayout.LEFT);
            logPanel = new JPanel();
            logPanel.setLayout(flowLayout);
            logPanel.setBorder(BorderFactory.createTitledBorder(null,"Activity Log", TitledBorder.DEFAULT_JUSTIFICATION,TitledBorder.DEFAULT_POSITION, new Font("Dialog",Font.BOLD,12), new Color(51, 51, 51)));
            logPanel.add(getClearButton(),null);
            logPanel.add(getPauseButton(),null);
            logPanel.add(getSuppressDuplicatesButton(),null);
        }
        return logPanel;
    }

	
    private JScrollPane getReadLogScrollPane() {
        readLogTextArea = new JTextArea();
        readLogTextArea.setSize(380,390);
        readLogScrollPane = new JScrollPane(readLogTextArea);
        readLogScrollPane.setPreferredSize(new Dimension(390,400));
        return readLogScrollPane;
    }

	
    private JButton getSendX10CommandButton() {
        if (sendX10CommandButton == null) {
            sendX10CommandButton = new JButton();
            sendX10CommandButton.setText("Send Command");
            sendX10CommandButton.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    House house = House.valueOf(commandHouseCodeComboBox.getSelectedItem().toString());
                    Device device = Device.getDeviceFromOrdinal(Integer.parseInt(deviceCodeComboBox.getSelectedItem().toString()));
                    Function function = Function.valueOf(functionCodeComboBox.getSelectedItem().toString());
                    Media media = Media.valueOf(commandMediaComboBox.getSelectedItem().toString());
                    X10Command x10Command = new X10Command(house, device, function, 0, media, "GUI");
                    guiManager.transmitEvent(x10Command);
                }
            });
        }
        return sendX10CommandButton;
    }
	
    private JButton getSendX10RemoteButton() {
        if (sendX10RemoteButton == null) {
            sendX10RemoteButton = new JButton();
            sendX10RemoteButton.setText("Send Remote");
            sendX10RemoteButton.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    House house = House.valueOf(remoteHouseCodeComboBox.getSelectedItem().toString());
                    Remote remote = Remote.valueOf(remoteCodeComboBox.getSelectedItem().toString());
                    X10Remote x10Remote = new X10Remote(house, Device.D1, remote, "GUI");
                    guiManager.transmitEvent(x10Remote);
                }
            });
        }
        return sendX10RemoteButton;
    }

    private JButton getInterfaceStatusButton() {
        if (statusButton == null) {
            statusButton = new JButton();
            statusButton.setText("CM15A Status");
            statusButton.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    X10InterfaceRequest request = new X10InterfaceRequest(InterfaceMessage.STATUS_REQUEST_0X8B, (byte)0x0, (byte)0x0, "GUI");
                    guiManager.transmitEvent(request);
                }
            });
        }
        return statusButton;
    }
	
	
    private JButton getClearButton() {
        if (clearButton == null) {
            clearButton = new JButton();
            clearButton.setText("Clear Log");
            clearButton.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    readLogTextArea.setText("");
                }
            });
        }
        return clearButton;
    }
	
    private JButton getSuppressDuplicatesButton() {
        if (suppressDuplicatesButton == null) {
            suppressDuplicatesButton = new JButton();
            suppressDuplicatesButton.setText("Allow Duplicate Entries");
            suppressDuplicatesButton.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    if(suppressDuplicateLogEntries) {
                        suppressDuplicateLogEntries = false;
                        suppressDuplicatesButton.setText("Suppress Duplicate Entries");
                    } else {
                        suppressDuplicateLogEntries = true;
                        suppressDuplicatesButton.setText("Allow Duplicate Entries");
                    }
                }
            });
        }
        return suppressDuplicatesButton;
    }

    private JButton getPauseButton() {
        if (pauseButton == null) {
            pauseButton = new JButton();
            pauseButton.setText("Pause");
            pauseButton.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    if(pause) {
                        pause = false;
                        pauseButton.setText("Pause");
                    } else {
                        pause = true;
                        pauseButton.setText("Restart");
                    }
                }
            });
        }
        return pauseButton;
    }

    private JComboBox getRemoteCodeComboBox() {
        Remote[] remoteCodes = Remote.values();

        if( remoteCodeComboBox == null) {
            remoteCodeComboBox = new JComboBox();
            for(Remote remote: remoteCodes){
                remoteCodeComboBox.addItem(remote.toString());
            }
        }
        return remoteCodeComboBox;
    }

    private JComboBox getCommandHouseCodeComboBox() {
        House[] houseCodes = House.values();

        if( commandHouseCodeComboBox == null) {
            commandHouseCodeComboBox = new JComboBox();
            for(House house: houseCodes){
                commandHouseCodeComboBox.addItem(house.toString());
            }
        }
        return commandHouseCodeComboBox;
    }

    private JComboBox getCommandMediaComboBox() {
        Media[] mediaValues = Media.values();

        if( commandMediaComboBox == null) {
            commandMediaComboBox = new JComboBox();
            for(Media media: mediaValues){
                commandMediaComboBox.addItem(media.toString());
            }
        }
        return commandMediaComboBox;
    }

    private JComboBox getRemoteHouseCodeComboBox() {
        House[] houseCodes = House.values();

        if( remoteHouseCodeComboBox == null) {
            remoteHouseCodeComboBox = new JComboBox();
            for(House house: houseCodes){
                remoteHouseCodeComboBox.addItem(house.toString());
            }
        }
        return remoteHouseCodeComboBox;
    }

    private JComboBox getDeviceCodeComboBox() {
        Device[] deviceCodes = Device.values();
        if( deviceCodeComboBox == null) {
            deviceCodeComboBox = new JComboBox();
            for(Device device: deviceCodes){
                deviceCodeComboBox.addItem(device.toString());
            }
        }
        return deviceCodeComboBox;
    }
	
	
    private JComboBox getFunctionCodeComboBox() {
        Function[] functionCodes = Function.values();

        if( functionCodeComboBox == null) {
            functionCodeComboBox = new JComboBox();
            for(Function function: functionCodes){
                functionCodeComboBox.addItem(function.toString());
            }
        }
        return functionCodeComboBox;
    }


    public void addToLogTextArea(String theString) {
        Date date = new Date();
        int pos = 0;
        String[] data = theString.split("\n");
        while (pos < data.length) {
            readLogTextArea.insert("[" + date.toString() + "] " + data[pos] + "\n",0);
            pos++;
        }
    }
}
